#ifndef _VL_RTSP_PARSER__H_
#define _VL_RTSP_PARSER__H_

#include "defs.h"
#include "rtp.h"
#include "utils/buffer.h"
#include "utils/kmp.h"
#include <unordered_map>

namespace VLRTSP {

class RTSPParser {
public:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 18:08:59
	 * 
	 * RTSP 方法名
	 */
	enum RTSPMethod {
		OPTIONS = 0,
		DESCRIBE, 
		SETUP, 
		PLAY, 
		TEARDOWN, 
		GET_PARAMETER, 
		RTCP, 
		NONE,
	};

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 17:43:22
	 * 
	 * 构造函数
	 */
	explicit RTSPParser();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 18:04:44
	 * 
	 * 析构函数
	 */
	~RTSPParser();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 18:05:18
	 * 
	 * 解析 RTSP 请求消息头
	 * @param buffer 字节缓冲区
	 * @return 如果解析成功返回 true
	 */
	bool parseHeader(Buffer* buffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 18:14:06
	 * 
	 * 重置解析器
	 */
	void reset();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 16:25:11
	 * 
	 * 获取 RTSP 方法
	 * @return RTSP 方法
	 */
	RTSPParser::RTSPMethod getMethod();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 11:11:41
	 * 
	 * 获取 RTSP 方法名字符串
	 * @return RTSP 方法名字符串
	 */
	std::string getMethodStr();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 16:25:11
	 * 
	 * 获取访问 IP
	 * @return 访问 IP
	 */
	std::string getIp();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 16:26:27
	 * 
	 * 获取访问端口
	 * @return 访问端口
	 */
	uint32_t getPort();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 16:27:08
	 * 
	 * 获取地址路径前缀
	 * @return 地址路径前缀
	 */
	std::string getSuffix();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 18:00:54
	 * 
	 * 获取传输模式
	 * @return 传输模式
	 */
	TransportMode getTransportMode();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 11:09:02
	 * 
	 * 获取轨道 Id
	 * @return 轨道 Id
	 */
	uint32_t getTrackId();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 18:01:13
	 * 
	 * 获取 RTP 端口 / Channel
	 * @return RTP 端口 / Channel
	 */
	uint16_t getRTPSendPoint();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 18:01:34
	 * 
	 * 获取 RTCP 端口 / Channel
	 * @return RTCP 端口 / Channel
	 */
	uint16_t getRTCPSendPoint();

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 17:34:35
	 * 
	 * 获取媒体分发器 Id
	 * @return 媒体分发器 Id
	 */
	uint32_t getDispatcherId();

	/**
	 * +======================================================================================================================+
	 * @Author: CimZzz
	 * @Date: 2022-01-12 17:02:16
	 * 
	 * 代码分割块，以下内容涉及: 
	 * 
	 * 构建 RTSP 响应方法
	 * 
	 */

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 17:47:17
	 * 
	 * 构建未找到资源的响应
	 * @param buffer 字节缓冲区
	 */
	void buildNotFoundResponse(Buffer* buffer);
	
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 17:48:00
	 * 
	 * 构建服务器异常的响应
	 * @param buffer 字节缓冲区
	 */
	void buildServerErrorResponse(Buffer* buffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 17:48:46
	 * 
	 * 构建不支持传输方式的响应
	 * @param buffer 字节缓冲区
	 */
	void buildUnsupportedTransportResponse(Buffer* buffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 17:02:44
	 * 
	 * 构建 Options 方法响应报文
	 * @param buffer 字节缓冲区
	 */
	void buildOptionsResponse(Buffer* buffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 17:21:02
	 * 
	 * 构建 Describe 方法响应报文
	 * @param buffer 字节缓冲区
	 * @param sdpBuffer SDP 描述文件缓冲区
	 */
	void buildDescribeResponse(Buffer* buffer, Buffer* sdpBuffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 17:03:36
	 * 
	 * 构建 SETUP 方法响应报文
	 * @param buffer 字节缓冲区
	 * @param serverRTPPort 服务端 RTP 端口
	 * @param serverRTCPPort 服务端 RTCP 端口
	 * @param dispatchId 媒体数据分发器 Id
	 * 
	 * @note 使用 UDP 传输方式
	 */
	void buildSetupByUdpResponse(Buffer* buffer, uint16_t serverRTPPort, uint16_t serverRTCPPort, uint32_t dispatchId);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-17 00:23:33
	 * 
	 * 构建 SETUP 方法响应报文
	 * @param buffer 字节缓冲区
	 * @param dispatchId 媒体数据分发器 Id
	 * 
	 * @note 使用 TCP 传输方式
	 */
	void buildSetupByTcpResponse(Buffer* buffer, uint32_t dispatchId);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 17:03:36
	 * 
	 * 构建 PLAY 方法响应报文
	 * @param buffer 字节缓冲区
	 */
	void buildPlayResponse(Buffer* buffer);

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 18:48:17
	 * 
	 * 构建 TEARDOWN 方法响应报文
	 * @param buffer 字节缓冲区
	 */
	void buildTeardownResponse(Buffer* buffer);

private:
	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 13:07:39
	 * 
	 * crlf 匹配器
	 */
	KMP crlfMatcher;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 18:11:05
	 * 
	 * RTSP 方法名
	 */
	RTSPMethod method;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 11:11:05
	 * 
	 * RTSP 方法名字符串
	 */
	std::string methodStr;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 17:24:47
	 * 
	 * RTSP URL
	 */
	std::string url;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 15:47:48
	 * 
	 * IP 地址
	 */
	std::string ip;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 15:47:10
	 * 
	 * 端口
	 */
	uint32_t port;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 15:47:37
	 * 
	 * 前缀
	 */
	std::string suffix;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 22:31:25
	 * 
	 * Track Id
	 */
	int32_t trackId;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-12 15:48:05
	 * 
	 * 版本号
	 */
	std::string version;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 18:06:54
	 * 
	 * 消息序号
	 */
	std::string cseq;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 17:58:27
	 * 
	 * 传输模式
	 */
	TransportMode transport;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 17:59:00
	 * 
	 * RTP 端口 / Channel
	 */
	uint16_t rtpSendPoint;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-13 17:59:31
	 * 
	 * RTCP 端口 / Channel
	 */
	uint16_t rtcpSendPoint;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-14 17:34:05
	 * 
	 * 分发器 Id
	 */
	uint32_t dispatcherId;

	/**
	 * @Author: CimZzz
	 * @Date: 2022-01-11 18:13:55
	 * 
	 * 头部参数映射表
	 */
	std::unordered_map<std::string, std::string> headerParamsMap;
};


}

#endif //_VL_RTSP_PARSER__H_
